package batch.monitor.client;

import java.io.IOException;

import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class JMXConnection {
	private JMXConnector jmxConnector;
	private MBeanServerConnection mBeanServerConnection;
	private ObjectName objectName;
	private MBeanInfo mBeanInfo;

	private int retryCountOfInitJMXConnector = 5;
	private int retryCountOfInitMBeanServerConnection = 5;
	private int retryCountOfInitObjectName = 5;
	private int retryCountOfInitMBeanInfo = 500;
	
	public JMXConnector getJmxConnector() {
		return jmxConnector;
	}

	public void setJmxConnector(JMXConnector jmxConnector) {
		this.jmxConnector = jmxConnector;
	}

	public MBeanServerConnection getMBeanServerConnection() {
		return mBeanServerConnection;
	}

	public void setMBeanServerConnection(MBeanServerConnection msbc) {
		this.mBeanServerConnection = msbc;
	}

	public ObjectName getObjectName() {
		return objectName;
	}

	public void setObjectName(ObjectName objectName) {
		this.objectName = objectName;
	}

	public MBeanInfo getmBeanInfo() {
		return mBeanInfo;
	}

	public void setmBeanInfo(MBeanInfo mBeanInfo) {
		this.mBeanInfo = mBeanInfo;
	}

	public JMXConnection(String targetIp, String targetObjectName) {
		initJMXConnector(targetIp);
		initMBeanServerConnection();
		initObjectName(targetObjectName);
		initGetMBeanInfo();
	}

	private void initGetMBeanInfo() {
		int i = 0;
		while(mBeanInfo == null) {
			try {
				mBeanInfo = mBeanServerConnection.getMBeanInfo(objectName);
			} catch (Exception e) {
				if(i++ < retryCountOfInitMBeanInfo ) {
					e.printStackTrace();
				} else {
					throw new RuntimeException(e);
				}
			}
			System.out.println(i + "retry to initialize MBeanInfo...");
		}
	}

	private void initObjectName(String targetObjectName) {
		int i = 0;
		while(objectName == null) {
			try {
				objectName = new ObjectName(targetObjectName);
			} catch (Exception e) {
				if(i++ < retryCountOfInitObjectName) {
					e.printStackTrace();
				} else {
					throw new RuntimeException(e);
				}
			}
			System.out.println(i + " retry to initialize ObjectName...");
		}
	}

	private void initMBeanServerConnection() {
		int i = 0;
		while(mBeanServerConnection == null) {
			try {
				mBeanServerConnection = jmxConnector.getMBeanServerConnection();
			} catch (IOException e) {
				if(i++ < retryCountOfInitMBeanServerConnection) {
					e.printStackTrace();
				} else {
					throw new RuntimeException(e);
				}
			}
			System.out.println(i + " retry to initialize MBeanServerConnection...");
		}
	}

	private void initJMXConnector(String targetIp) {
		int i = 0;
		while(jmxConnector == null) {
			try {
				System.out.println("\nCreate an RMI connector client and connect it to the RMI connector server");
				JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + targetIp + "/jmxrmi");
				jmxConnector = JMXConnectorFactory.connect(url);
			} catch (Exception e) {
				if(i++ < retryCountOfInitJMXConnector) {
					e.printStackTrace();
				} else {
					throw new RuntimeException(e);
				}
			}
			System.out.println(i + " retry to initialize JMXConnector...");
		}
	}

	public void destroyJMXConnection() {
		try {
			if (jmxConnector != null) {
				jmxConnector.close();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
